//
// Ishtar C++ Utility Library
//
// Task Facility - Thread Pool Private Header
//

#ifndef __ISHTAR_TASK_THREAD_POOL_IMPL_H
#define __ISHTAR_TASK_THREAD_POOL_IMPL_H

#include <Ishtar/Ishtar.h>

#if defined( ISHTAR_COMPILER_HAS_PRAGMA_ONCE )
#pragma once
#endif

#include <boost/ptr_container/ptr_vector.hpp>
#include <Ishtar/Concurrent/ConcurrentDualQueue.h>
#include <Ishtar/Task/PooledThread.h>
#include <Ishtar/Task/ThreadPool.h>
#include <Ishtar/Task/WorkExecutorImpl.h>
#include <Ishtar/Task/WorkImpl.h>
#include <Ishtar/Thread/SimpleMutex.h>


namespace Ishtar
{

namespace Task
{

///////////////////////////////////////////////////////////////////////////////
//
// Thread Pool
//

class ThreadPoolImpl : public WorkExecutorImpl
{
public:
    ThreadPoolImpl( const std::string& name, Uint numThreads, ThreadPool& host );
    ~ThreadPoolImpl();

    std::string GetName() const { return m_name; }

    void Shutdown();

    void SubmitWork( const Work& w );
    void AddReadyWork( const WorkImplPtr& w );

    void AddReadyThread( PooledThread* thread );
    
    Bool IsShutdown()         const { return m_shutdown; }
    Uint GetNumWaitingWorks() const { return m_numWaitingWorks; }

    
private:

    void DispatchOne();  // try to dispatch one work

    void WakeThreadToExecuteWork( PooledThread* thread, const WorkImplPtr& work );

   
    //
    // Data members
    //

    std::string m_name;
    ThreadPool& m_host;

    Bool m_shutdown;
    
    InterlockedUint m_numWaitingWorks;

    boost::ptr_vector< PooledThread > m_threads;
  
    typedef Windows::SinglyLinkedList< PooledThread > ThreadStack;
    ThreadStack m_readyThreads;
    
    typedef ConcurrentDualQueue< WorkImplPtr, SimpleMutex > WorkQueue;
    WorkQueue m_readyWorks;
};


///////////////////////////////////////////////////////////////////////////////

} // namespace Task

} // namespace Ishtar

#endif // __ISHTAR_TASK_THREAD_POOL_IMPL_H
